# Test Case
# http://localhost:8080/?title_id=FAGP&title_id=RSPW01&title_id=RSPK01&title_id=RSPE01&title_id=RD2X41
# http://localhost:8080/?title_id=FAGP&title_id=RSPW01&title_id=RSPK01&title_id=RSPE01&title_id=RD2X41&friend_code=XXXX-YYYY-ZZZZZ-55555-77777&password=secret
# http://localhost:8080/?title_id=HACA&title_id=HADA&title_id=HAFP&title_id=HAXX&title_id=JODI&friend_code=XXXX-YYYY-ZZZZZ-55555-77777&password=secret
# http://localhost:8080/card?friend_code=XXXX-YYYY-ZZZZZ-55555-77777
# http://localhost:8080/?friend_code=1111-2222&password=secret&title_id=NABP

# Possible Backgrounds
# http://www.guiasnintendo.com/images/stories/ultimos_lanzamientos/9986.jpg  ...
# http://mediacontent.nintendo-europe.com/NOE/images/moods/games_allgames2_en.jpg


from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
from google.appengine.api import urlfetch
from google.appengine.ext import db

import copy


card_template = """
                <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" > 
                <html><head> 
                <!--<link rel="stylesheet" type="text/css" href="http://gamercard.xbox.com/xweb/lib/css/ExternalGamerCardSkin.css" />-->
	            <link rel="stylesheet" type="text/css" href="/static/card_files/ExternalGamerCardSkin.css" /> 
                <meta name="robots" content="noindex,nofollow" /> 
                <meta name="category" content="Gamercard" /> 
                <base target="_top"> 
                </head>
		
		<body><div class="XbcgcContainer"><div class="Xbcgc"><h3 class="XbcGamertagSilver">
		<span class="XbcFLAL">#USERNAME#</span></h3>
		
		<!--<div class="XbcgcInfo"><a href="http://live.xbox.com/member/#USERNAME#">
		<img class="XbcgcGamertile" height="64" width="64" src="http://image.xboxlive.com/global/t.4d538827/tile/0/20006" 
		alt="Mass Effect LCE" title="Mass Effect LCE" /></a>
		<div class="XbcgcStats"><p><span class="XbcFLAL">Rep</span><span class="XbcFRAR">
		<img src="http://gamercard.xbox.com/xweb/lib/images/gc_repstars_external_12.gif" /></span></p>
		<p><span class="XbcFLAL"><img alt="Puntuacion de jugador" src="http://gamercard.xbox.com/xweb/lib/images/G_Icon_External.gif" /></span>
		<span class="XbcFRAR">4345</span></p><p><span class="XbcFLAL">Zona</span><span class="XbcFRAR">Informal</span></p></div></div>-->
		
		<div class="XbcgcGames"><a href="#HREF1#" target="_blank"><img height="84" width="64" title="#TITLE1#" alt="" src="#COVER1#" /></a><a href="#HREF2#" target="_blank"><img height="84" width="64" title="#TITLE2#" alt="" src="#COVER2#" /></a><a href="#HREF3#" target="_blank"><img height="84" width="64" title="#TITLE3#" alt="" src="#COVER3#" /></a><a href="#HREF4#" target="_blank"><img height="84" width="64" title="#TITLE4#" alt="" src="#COVER4#" /></a><a href="#HREF5#" target="_blank"><img height="84" width="64" title="#TITLE5#" alt="" src="#COVER5#" /></a></div></div></div></body></html>
"""


def getRegion(tid):
	# Check region letter and get region code
	region = "EN"
	if tid[3] == "P":
		region = "EN"
	elif tid[3] == "A":
		region = "EN"
	elif tid[3] == "E":
		region = "US"
	elif tid[3] == "J":
		region = "JA"
	elif tid[3] == "K":
		region = "KO"
	elif tid[3] == "W":
		region = "ZH"
	elif tid[3] == "R":
		region = "RU"	
	return region


class CardEntry(db.Model):
	friend_code = db.StringProperty()
	password = db.StringProperty()
	game1 = db.StringProperty()
	game2 = db.StringProperty()
	game3 = db.StringProperty()
	game4 = db.StringProperty()
	game5 = db.StringProperty()
	cover1 = db.StringProperty()
	cover2 = db.StringProperty()
	cover3 = db.StringProperty()
	cover4 = db.StringProperty()
	cover5 = db.StringProperty()


class MainPage(webapp.RequestHandler):
    """
    Transform a special real tid (e.g. a system channel tid) into a WiiTDB custom tid 
    """
    def transform_title(self, tid):
	new_tid = tid
	# Opera Internet Channel
	if tid[0:3] == "HAD":
		new_tid = "CICP00"
	# Check Mii Out
	elif tid[0:3] == "HAP":
		new_tid = "CCCP00"
	# Photo Channel 1.1
	elif tid[0:3] == "HAZ":
		new_tid = "CPCP00"
	# Photo Channel 1.0
	elif tid[0:3] == "HAA":
		new_tid = "CPCP00"
	# Shopping Channel
	elif tid[0:3] == "HAB":
		new_tid = "CSCP00"
	# Mii Channel
	elif tid[0:3] == "HAC":
		new_tid = "CMIP00"
	# Weather Channel
	elif tid[0:3] == "HAF":
		new_tid = "CWCE00"
	# News Channel
	elif tid[0:3] == "HAG":
		new_tid = "CNCE00"
	# Homebrew Channel
	elif tid[0:4] == "HAXX":
		new_tid = "CHCP00"
	# New Homebrew Channel
	elif tid[0:4] == "JODI":
		new_tid = "CHCP00"	
	return new_tid


    """
    Validate a tid against WiiTDB and get the url of its cover (or title) image
    """
    def validate_title(self, tid):
	region = getRegion(tid)
		
	# Validate title_id with or without 2-digit code
	url = "http://wiitdb.com/wiitdb/artwork/cover/"+region+"/"+tid+".png"
	self.response.out.write("Trying http://wiitdb.com/wiitdb/artwork/cover/"+region+"/"+tid+".png\n")
	result = urlfetch.fetch(url)
	if result.status_code != 200:
		# Couldn't find the cover image, let's try with the wwtitle image
		url = "http://wiitdb.com/wiitdb/artwork/wwtitle/"+region+"/"+tid+".png"
		self.response.out.write("Trying http://wiitdb.com/wiitdb/artwork/wwtitle/"+region+"/"+tid+".png\n")
		result = urlfetch.fetch(url)
		if result.status_code != 200:
			# The title_id is invalid. Let's remove the last two digits
			tid = tid[0:4]
			url = "http://wiitdb.com/wiitdb/artwork/cover/"+region+"/"+tid+".png"
			self.response.out.write("Trying http://wiitdb.com/wiitdb/artwork/cover/"+region+"/"+tid+".png\n")
			result = urlfetch.fetch(url)
			if result.status_code != 200:
				# Couldn't find the cover image, let's try with the wwtitle image
				url = "http://wiitdb.com/wiitdb/artwork/wwtitle/"+region+"/"+tid+".png"
				self.response.out.write("Trying http://wiitdb.com/wiitdb/artwork/wwtitle/"+region+"/"+tid+".png\n")
				result = urlfetch.fetch(url)
				if result.status_code != 200:
					#The title_id is completely wrong (or does not have an entry in WiiTDB)
					self.response.out.write("The title id "+tid+" is wrong!\n")
					return ""
	return url

    def get(self):
        self.response.headers['Content-Type'] = 'text/plain'
        self.response.out.write('WiiGamercard Service')
        #self.response.out.write(str(dir(self.request)))
        #self.response.out.write('\n')
        #self.response.out.write(self.request.str_GET)
        self.response.out.write('\n')
	
	friend_code = ""
	password = ""
	game_list = list()
	cover_dict = dict()
        
	for a,v in self.request.str_GET.items():
            self.response.out.write(a)
            self.response.out.write(" ")
            self.response.out.write(v)
            self.response.out.write('\n')
            if str(a) == "title_id":
		tid = v.upper()
		tid = self.transform_title(tid)
		url = self.validate_title(tid)
		if url:
			# Let's assume that the title_id is valid
			if tid in game_list:
				game_list.remove(tid)
			game_list.insert(0, tid)
			# Keep the url for the cover of this tid
			cover_dict[tid] =url
		
	    elif str(a) == "friend_code":
		    # Clean the friend code of unwanted characters (leave only numbers and letters)
		    friend_code = v.replace("-", "").replace("_","")
	    elif str(a) == "password":
		    password = v
        self.response.out.write(game_list)
	
	if not friend_code and not password:
		# Error, there is no user information
		return

	# Query the DB for a card entry for this friend code
	cardentries =[]
        cardentries = db.GqlQuery("SELECT * FROM CardEntry WHERE friend_code = :1 ORDER BY friend_code DESC LIMIT 1", friend_code)
	
        # If there is already a card entry with this friend code, get its 'old' game list and then delete it
        old_game_list = list()
	if cardentries:
		for ce in cardentries:
			if ce.game5:
				old_game_list.insert(0, ce.game5)
			if ce.game4:
				old_game_list.insert(0, ce.game4)
			if ce.game3:
				old_game_list.insert(0, ce.game3)
			if ce.game2:
				old_game_list.insert(0, ce.game2)
			if ce.game1:
				old_game_list.insert(0, ce.game1)
			ce.delete()
			self.response.out.write("Previous entry deleted")

	game_list.reverse()
	# Build an updated 5-game list based on the old and new lists
	# DISABLED FOR NOW
	"""
        for tid in game_list:
		old_game_list.insert(0, tid)
	game_list = old_game_list[0:5]
	"""

	self.response.out.write("\nDefinitive Game List: "+str(game_list)+"\n")

	# Insert a new card entry in the DB
	entry = CardEntry()
	entry.friend_code = friend_code
	entry.password = password
	entry.game5 = ""
	entry.game4 = ""
	entry.game3 = ""
	entry.game2 = ""
	entry.game1 = ""
	entry.cover5 = ""
	entry.cover4 = ""
	entry.cover3 = ""
	entry.cover2 = ""
	entry.cover1 = ""
	
	if len(game_list) >= 5:
		entry.game5 = game_list[4]
		entry.cover5 = cover_dict[game_list[4]]
	if len(game_list) >= 4:
		entry.game4 = game_list[3]
		entry.cover4 = cover_dict[game_list[3]]
	if len(game_list) >= 3:
		entry.game3 = game_list[2]
		entry.cover3 = cover_dict[game_list[2]]
	if len(game_list) >= 2:
		entry.game2 = game_list[1]
		entry.cover2 = cover_dict[game_list[1]]
	if len(game_list) >= 1:
		entry.game1 = game_list[0]
		entry.cover1 = cover_dict[game_list[0]]
	entry.put()
	out = entry.friend_code+entry.password+entry.game1+entry.game2+entry.game3+entry.game4+entry.game5
	out += entry.cover1 + entry.cover2 + entry.cover3 + entry.cover4 + entry.cover5 
	self.response.out.write(out)
	
        
class CardPage(webapp.RequestHandler):
    def get(self):
        try:
            friend_code = ""
            # Get the friend code
            for a,v in self.request.str_GET.items():
                if a == "friend_code":
		    # Clean the friend code of unwanted characters (leave only numbers and letters)
                    friend_code = v.replace("-", "").replace("_","")

            # If there is no requested friend code, return
            if not friend_code:
                return

            # Get the card entry of the requested friend code
            #cardentries = db.GqlQuery("SELECT * FROM CardEntry ORDER BY friend_code DESC LIMIT 1")
	    cardentries = db.GqlQuery("SELECT * FROM CardEntry WHERE friend_code = :1 ORDER BY friend_code DESC LIMIT 1", friend_code)

            # Check wether there is no card entry with this friend code
            if cardentries.count() == 0:
                return

            game_list = list()
	    cover_dict = dict()
            for entry in cardentries:
                if entry.game5:
                    game_list.insert(0, entry.game5)
		    cover_dict[entry.game5] = entry.cover5
                if entry.game4:
                    game_list.insert(0, entry.game4)
		    cover_dict[entry.game4] = entry.cover4
                if entry.game3:
                    game_list.insert(0, entry.game3)
		    cover_dict[entry.game3] = entry.cover3
                if entry.game2:
                    game_list.insert(0, entry.game2)
		    cover_dict[entry.game2] = entry.cover2
                if entry.game1:
                    game_list.insert(0, entry.game1)
		    cover_dict[entry.game1] = entry.cover1

	    #self.response.headers['Content-Type'] = 'text/plain'
    	    #r = """<table><tr>"""
    	    r = copy.copy(card_template)
            r = r.replace("#USERNAME#", entry.friend_code)
    	    i = 1
    	    for tid in game_list:
        	region = getRegion(tid)
        	if i > 5:
        		break
        	r = r.replace("#TITLE"+str(i)+"#", tid)
        	#r = r.replace("#COVER"+str(i)+"#", "http://wiitdb.com/wiitdb/artwork/cover/"+region+"/"+tid+".png")
		r = r.replace("#COVER"+str(i)+"#", str(cover_dict[tid]))
        	r = r.replace("#HREF"+str(i)+"#", "http://wiitdb.com/Game/"+tid)
        	i = i + 1
            self.response.out.write(r)
        except Exception,e:
            self.response.out.write(str(e))
        
            


application = webapp.WSGIApplication(
                                     [('/', MainPage), ('/card', CardPage)],
                                     debug=True)

def main():    
    run_wsgi_app(application)

if __name__ == "__main__":
    main()
    
